//
//  TalkfunSocketSDK.swift
//  TalkfunSocket
//
//  Created by moRui on 2024/10/16.
//  Copyright © 2024 莫瑞权. All rights reserved.
//

import UIKit
import SocketIO

public typealias TalkfunSocketSDKCallback = ([Any]) -> ()
/** @objc
  
 公开
 public 决定是否能在 OC类中使用这个类
 */
public class TalkfunSocketSDK: NSObject {
    

    
    // 将 manager 作为属性
    @objc public var manager: SocketManager?

    @objc public func createSocketManager(socketURL: URL, config: [String: Any]?) {
         self.manager = SocketManager(socketURL: socketURL, config: config)
        //如果为“true”，则每次调用“connect”时，都会创建一个新引擎。
//        self.manager?.forceNew = false
//        //启用重连，
//        self.manager?.reconnects = false
//        //尝试重新连接之前等待的最少秒数。
//        self.manager?.reconnectWait = 0
//        //尝试重新连接之前等待的最大秒数。
//        self.manager?.reconnectWaitMax = 0

    }
    
    
    @objc public func get_defaultSocket_sid() -> String {
        if let sid = self.manager?.defaultSocket.sid {
            return sid
        }
        return ""
    }
    
    @objc public func get_defaultSocket() -> SocketIOClient? {
        guard let validManager = self.manager else {
            print("Error: SocketManager is nil.")
            return nil
        }
        return validManager.defaultSocket
    }

    @objc public func on(event: String, callback: @escaping TalkfunSocketSDKCallback) {
        if let validManager = self.manager {
            validManager.defaultSocket.on(event) { data, ack in
                callback(data)
            }
        }
    }
    
    @objc public func on(emitWithAck: String, withArray: NSArray, timeoutAfter: Double, callback: @escaping TalkfunSocketSDKCallback) {
        if let validManager = self.manager {
            var socketDataArray: [SocketData] = []

            for item in withArray {
                if let socketDataItem = item as? SocketData {
                    socketDataArray.append(socketDataItem)
                } else {
                    print("Error: Item in array does not conform to SocketData")
                }
            }

            validManager.defaultSocket.emitWithAck(emitWithAck, with: socketDataArray).timingOut(after: timeoutAfter) { data in
                callback(data)
            }
        }
    }
    
    @objc public func emit(emitWithAck: String, withArray: NSArray) {
        if let validManager = self.manager {
            var socketDataArray: [SocketData] = []
            
            for item in withArray {
                if let socketDataItem = item as? SocketData {
                    socketDataArray.append(socketDataItem)
                } else {
                    print("Error: Item in array does not conform to SocketData")
                }
            }
            validManager.defaultSocket.emit(emitWithAck, with: socketDataArray) {
                
            }
        }
    }
    
    @objc public func connect() {
        if let validManager = self.manager {
            validManager.defaultSocket.connect()
        }
    }
    
    @objc public func disconnect(broadcastEvent: String) {
        if let validManager = self.manager {
            validManager.defaultSocket.off("connect")
            validManager.defaultSocket.off("reconnect")
            validManager.defaultSocket.off("error")
            validManager.defaultSocket.off("reconnectAttempt")
            validManager.defaultSocket.off("disconnect")
            validManager.defaultSocket.off("member:join:me")
            validManager.defaultSocket.off("member:join:me")
            validManager.defaultSocket.off(broadcastEvent)
            validManager.defaultSocket.disconnect()
            validManager.disconnect()
        }
    }
    
    @objc public func onAny(callback: @escaping TalkfunSocketSDKCallback) {
        if let validManager = self.manager {
            validManager.defaultSocket.onAny { event in
                callback([event])
            }
        }
    }
    
    @objc public func shutdown() {
        if let validManager = self.manager {
            // 先断开所有连接
            disconnect(broadcastEvent: "_broadcast")
            
            // 将 manager 设置为 nil，彻底释放
            self.manager = nil
            
            print("SocketManager has been killed and released")
        } else {
            print("SocketManager is already nil")
        }
    }
}

struct TalkfunSocketSDKData: SocketData {
    var message: String

    func socketRepresentation() throws -> SocketData {
        return self
    }
}
